package com.huaxin.device.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huaxin.device.dto.ResponseCode;
import com.huaxin.device.dto.ResponseResult;
import com.huaxin.device.dto.request.CollectedDataRecordCreateReqDTO;
import com.huaxin.device.dto.request.CollectedDataRecordPageListReqDTO;
import com.huaxin.device.dto.request.CollectedDataRecordUpdateReqDTO;
import com.huaxin.device.mapper.CollectedDataRecordMapper;
import com.huaxin.device.mapping.CollectedDataRecordMapping;
import com.huaxin.device.models.CollectedDataRecord;
import com.huaxin.device.service.CollectedDataRecordService;
import com.huaxin.hxenum.enums.DataQuality;
import com.huaxin.hxenum.enums.DataType;
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.webjars.NotFoundException;

import static org.springframework.util.StringUtils.hasText;

@Service
@RequiredArgsConstructor
public class CollectedDataRecordServiceImpl extends ServiceImpl<CollectedDataRecordMapper, CollectedDataRecord> implements CollectedDataRecordService {

    private final ApplicationContext applicationContext;
    private final CollectedDataRecordMapping mapping;

    @Override
    public ResponseResult<CollectedDataRecord> create(CollectedDataRecordCreateReqDTO in) {
        if (in == null) {
            return ResponseResult.parameterError(null, "参数为空");
        }

        CollectedDataRecord entity = mapping.toEntity(in);
        if (!save(entity)) {
            return ResponseResult.failure(ResponseCode.INTERNAL_SERVER_ERROR, "创建失败", null);
        }
        CollectedDataRecord created = this.getById(entity.getId());
        return ResponseResult.ok(created);
    }

    @Override
    public CollectedDataRecord getByRecordId(String id) {
        if (!hasText(id)) {
            throw new IllegalArgumentException("采集数据记录ID不能为空");
        }
        CollectedDataRecord record = this.getById(id);
        if (record == null) {
            throw new NotFoundException("采集数据记录不存在");
        }
        return record;
    }

    @Override
    public ResponseResult<String> update(CollectedDataRecordUpdateReqDTO in) {
        if (in == null) {
            return ResponseResult.parameterError(null, "参数为空");
        }

        CollectedDataRecord entity = this.getByRecordId(in.getId());

        mapping.updateEntity(in, entity);
        if (!updateById(entity)) {
            return ResponseResult.failure(ResponseCode.INTERNAL_SERVER_ERROR, "更新失败", null);
        }
        return ResponseResult.ok("更新成功");
    }

    @Override
    public ResponseResult<String> delete(String id) {
        CollectedDataRecord entity = this.getByRecordId(id);
        boolean removed = this.applicationContext.getBean(CollectedDataRecordService.class).removeById(id);
        if (!removed) {
            return ResponseResult.failure(ResponseCode.CUSTOM_BUSINESS_ERROR, "删除失败或记录不存在", null);
        }
        return ResponseResult.ok("删除成功");
    }

    @Override
    public ResponseResult<IPage<CollectedDataRecord>> pageQuery(CollectedDataRecordPageListReqDTO in) {
        if (in == null) {
            return ResponseResult.parameterError(null, "分页参数为空");
        }

        IPage<CollectedDataRecord> page = new Page<>(in.getPageNum(), in.getPageSize());
        LambdaQueryWrapper<CollectedDataRecord> wrapper = new LambdaQueryWrapper<>();

        if (hasText(in.getCollectorId())) {
            wrapper.eq(CollectedDataRecord::getCollectorId, in.getCollectorId());
        }
        if (hasText(in.getDeviceSerial())) {
            wrapper.eq(CollectedDataRecord::getDeviceSerial, in.getDeviceSerial());
        }
        if (hasText(in.getEquipmentId())) {
            wrapper.eq(CollectedDataRecord::getEquipmentId, in.getEquipmentId());
        }
        if (hasText(in.getMetricCode())) {
            wrapper.eq(CollectedDataRecord::getMetricCode, in.getMetricCode());
        }
        if (hasText(in.getValueType())) {
            wrapper.eq(CollectedDataRecord::getValueType, DataType.of(in.getValueType()));
        }
        if (hasText(in.getQuality())) {
            wrapper.eq(CollectedDataRecord::getQuality, DataQuality.valueOf(in.getQuality().trim().toLowerCase()));
        }

        if (in.getCollectedAtStart() != null) {
            wrapper.ge(CollectedDataRecord::getCollectedAt, in.getCollectedAtStart());
        }
        if (in.getCollectedAtEnd() != null) {
            wrapper.le(CollectedDataRecord::getCollectedAt, in.getCollectedAtEnd());
        }

        if (hasText(in.getKeyword())) {
            wrapper.and(w -> w.like(CollectedDataRecord::getDataName, in.getKeyword()));
        }

        wrapper.orderByDesc(CollectedDataRecord::getCollectedAt);

        IPage<CollectedDataRecord> result = this.page(page, wrapper);
        return ResponseResult.ok(result);
    }
}